home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 2.iso / dist / fw_gsl.idb / usr / freeware / info / gsl-ref.info-11.z / gsl-ref.info-11
Text File  |  2000-10-09  |  51KB  |  1,298 lines

  1. This is gsl-ref.info, produced by Makeinfo version 3.12h from
  2. gsl-ref.texi.
  3.  
  4. INFO-DIR-SECTION Scientific software
  5. START-INFO-DIR-ENTRY
  6. * gsl-ref: (gsl-ref).                   GNU Scientific Library - Reference
  7. END-INFO-DIR-ENTRY
  8.  
  9.    This file documents the GNU Scientific Library.
  10.  
  11.    Copyright (C) 1996, 1997, 1998, 1999 The GSL Project.
  12.  
  13.    Permission is granted to make and distribute verbatim copies of this
  14. manual provided the copyright notice and this permission notice are
  15. preserved on all copies.
  16.  
  17.    Permission is granted to copy and distribute modified versions of
  18. this manual under the conditions for verbatim copying, provided that
  19. the entire resulting derived work is distributed under the terms of a
  20. permission notice identical to this one.
  21.  
  22.    Permission is granted to copy and distribute translations of this
  23. manual into another language, under the above conditions for modified
  24. versions, except that this permission notice may be stated in a
  25. translation approved by the Foundation.
  26.  
  27. 
  28. File: gsl-ref.info,  Node: Root Finding Examples,  Next: Root Finding References and Further Reading,  Prev: Root Finding Algorithms using Derivatives,  Up: One dimensional Root-Finding
  29.  
  30. Examples
  31. ========
  32.  
  33.    For any root finding algorithm we need to prepare the function to be
  34. solved.  For this example we will use the general quadratic equation
  35. described earlier.  We first need a header file (`demo_fn.h') to define
  36. the function parameters,
  37.  
  38.      struct quadratic_params
  39.        {
  40.          double a, b, c;
  41.        };
  42.      
  43.      double quadratic (double x, void *params);
  44.      double quadratic_deriv (double x, void *params);
  45.      void quadratic_fdf (double x, void *params, double *y, double *dy);
  46.  
  47. We place the function definitions in a separate file (`demo_fn.c'),
  48.  
  49.      double
  50.      quadratic (double x, void *params)
  51.      {
  52.        struct quadratic_params *p = (struct quadratic_params *) params;
  53.      
  54.        double a = p->a;
  55.        double b = p->b;
  56.        double c = p->c;
  57.      
  58.        return (a * x + b) * x + c;
  59.      }
  60.      
  61.      double
  62.      quadratic_deriv (double x, void *params)
  63.      {
  64.        struct quadratic_params *p = (struct quadratic_params *) params;
  65.      
  66.        double a = p->a;
  67.        double b = p->b;
  68.        double c = p->c;
  69.      
  70.        return 2.0 * a * x + b;
  71.      }
  72.      
  73.      void
  74.      quadratic_fdf (double x, void *params, double *y, double *dy)
  75.      {
  76.        struct quadratic_params *p = (struct quadratic_params *) params;
  77.      
  78.        double a = p->a;
  79.        double b = p->b;
  80.        double c = p->c;
  81.      
  82.        *y = (a * x + b) * x + c;
  83.        *dy = 2.0 * a * x + b;
  84.      }
  85.  
  86. The first program uses the function solver `gsl_root_fsolver_brent' for
  87. Brent's method and the general quadratic defined above to solve the
  88. following equation,
  89.  
  90.      x^2 - 5 = 0
  91.  
  92. with solution x = \sqrt 5 = 2.236068...
  93.  
  94.      #include <stdio.h>
  95.      #include <gsl/gsl_errno.h>
  96.      #include <gsl/gsl_math.h>
  97.      #include <gsl/gsl_roots.h>
  98.      
  99.      #include "demo_fn.h"
  100.      #include "demo_fn.c"
  101.      
  102.      int
  103.      main ()
  104.      {
  105.        int status;
  106.        int iterations = 0, max_iterations = 100;
  107.        gsl_root_fsolver *s;
  108.        double r = 0, r_expected = sqrt (5.0);
  109.        gsl_interval x = {0.0, 5.0};
  110.        gsl_function F;
  111.        struct quadratic_params params = {1.0, 0.0, -5.0};
  112.      
  113.        F.function = &quadratic;
  114.        F.params = ¶ms;
  115.      
  116.        s = gsl_root_fsolver_alloc (gsl_root_fsolver_brent, &F, x);
  117.      
  118.        printf ("using %s method\n", gsl_root_fsolver_name (s));
  119.      
  120.        printf ("%5s [%9s, %9s] %9s %9s %10s %9s\n",
  121.                "iter", "lower", "upper", "root", "actual", "err", "err(est)");
  122.      
  123.        do
  124.          {
  125.            iterations++;
  126.            status = gsl_root_fsolver_iterate (s);
  127.            r = gsl_root_fsolver_root (s);
  128.            x = gsl_root_fsolver_interval (s);
  129.            status = gsl_root_test_interval (x, 0, 0.001);
  130.      
  131.            if (status == GSL_SUCCESS)
  132.              printf ("Converged:\n");
  133.      
  134.            printf ("%5d [%.7f, %.7f] %.7f %.7f %+.7f %.7f\n",
  135.                    iterations, x.lower, x.upper,
  136.                    r, r_expected, r - r_expected, x.upper - x.lower);
  137.          }
  138.        while (status == GSL_CONTINUE && iterations < max_iterations);
  139.      
  140.      }
  141.  
  142. Here are the results of the iterations,
  143.  
  144.      bash$ ./a.out
  145.      using brent method
  146.       iter [    lower,     upper]      root    actual        err  err(est)
  147.          1 [1.0000000, 5.0000000] 1.0000000 2.2360680 -1.2360680 4.0000000
  148.          2 [1.0000000, 3.0000000] 3.0000000 2.2360680 +0.7639320 2.0000000
  149.          3 [2.0000000, 3.0000000] 2.0000000 2.2360680 -0.2360680 1.0000000
  150.          4 [2.2000000, 3.0000000] 2.2000000 2.2360680 -0.0360680 0.8000000
  151.          5 [2.2000000, 2.2366300] 2.2366300 2.2360680 +0.0005621 0.0366300
  152.      Converged:
  153.          6 [2.2360634, 2.2366300] 2.2360634 2.2360680 -0.0000046 0.0005666
  154.  
  155. If the program is modified to use the bisection solver instead of
  156. Brent's method, by changing `gsl_root_fsolver_brent' to
  157. `gsl_root_fsolver_bisection' the slower convergence of the Bisection
  158. method can be observed,
  159.  
  160.      bash$ ./a.out
  161.      using bisection method
  162.       iter [    lower,     upper]      root    actual        err  err(est)
  163.          1 [0.0000000, 2.5000000] 1.2500000 2.2360680 -0.9860680 2.5000000
  164.          2 [1.2500000, 2.5000000] 1.8750000 2.2360680 -0.3610680 1.2500000
  165.          3 [1.8750000, 2.5000000] 2.1875000 2.2360680 -0.0485680 0.6250000
  166.          4 [2.1875000, 2.5000000] 2.3437500 2.2360680 +0.1076820 0.3125000
  167.          5 [2.1875000, 2.3437500] 2.2656250 2.2360680 +0.0295570 0.1562500
  168.          6 [2.1875000, 2.2656250] 2.2265625 2.2360680 -0.0095055 0.0781250
  169.          7 [2.2265625, 2.2656250] 2.2460938 2.2360680 +0.0100258 0.0390625
  170.          8 [2.2265625, 2.2460938] 2.2363281 2.2360680 +0.0002601 0.0195312
  171.          9 [2.2265625, 2.2363281] 2.2314453 2.2360680 -0.0046227 0.0097656
  172.         10 [2.2314453, 2.2363281] 2.2338867 2.2360680 -0.0021813 0.0048828
  173.         11 [2.2338867, 2.2363281] 2.2351074 2.2360680 -0.0009606 0.0024414
  174.      Converged:
  175.         12 [2.2351074, 2.2363281] 2.2357178 2.2360680 -0.0003502 0.0012207
  176.  
  177.    The next program solves the same function using a derivative solver
  178. instead.
  179.  
  180.      #include <stdio.h>
  181.      #include <gsl/gsl_errno.h>
  182.      #include <gsl/gsl_math.h>
  183.      #include <gsl/gsl_roots.h>
  184.      
  185.      #include "demo_fn.h"
  186.      #include "demo_fn.c"
  187.      
  188.      int
  189.      main ()
  190.      {
  191.        int status;
  192.        int iterations = 0, max_iterations = 100;
  193.        gsl_root_fdfsolver *s;
  194.        double x0, x = 5.0, r_expected = sqrt (5.0);
  195.        gsl_function_fdf FDF;
  196.        struct quadratic_params params = {1.0, 0.0, -5.0};
  197.      
  198.        FDF.f = &quadratic;
  199.        FDF.df = &quadratic_deriv;
  200.        FDF.fdf = &quadratic_fdf;
  201.        FDF.params = ¶ms;
  202.      
  203.        s = gsl_root_fdfsolver_alloc (gsl_root_fdfsolver_newton, &FDF, x);
  204.      
  205.        printf ("using %s method\n", gsl_root_fdfsolver_name (s));
  206.      
  207.        printf ("%-5s %10s %10s %10s %10s\n",
  208.                "iter", "root", "actual", "err", "err(est)");
  209.        do
  210.          {
  211.            iterations++;
  212.            status = gsl_root_fdfsolver_iterate (s);
  213.            x0 = x;
  214.            x = gsl_root_fdfsolver_root (s);
  215.            status = gsl_root_test_delta (x, x0, 0, 0.001);
  216.      
  217.            if (status == GSL_SUCCESS)
  218.              printf ("Converged:\n");
  219.      
  220.            printf ("%5d %10.7f %10.7f %+10.7f %10.7f\n",
  221.                    iterations, x, r_expected, x - r_expected, x - x0);
  222.          }
  223.        while (status == GSL_CONTINUE && iterations < max_iterations);
  224.      
  225.      }
  226.  
  227.    Here are the results for Newton's method,
  228.  
  229.      bash$ ./a.out
  230.      using newton method
  231.      iter        root     actual        err   err(est)
  232.          1  3.0000000  2.2360680 +0.7639320 -2.0000000
  233.          2  2.3333333  2.2360680 +0.0972654 -0.6666667
  234.          3  2.2380952  2.2360680 +0.0020273 -0.0952381
  235.      Converged:
  236.          4  2.2360689  2.2360680 +0.0000009 -0.0020263
  237.  
  238. Note that the error can be estimated more accurately by taking the
  239. difference between the current iterate and next iterate rather than the
  240. previous iterate.  The other derivative solvers can be investigated by
  241. changing `gsl_root_fdfsolver_newton' to `gsl_root_fdfsolver_secant' or
  242. `gsl_root_fdfsolver_steffenson'.
  243.  
  244. 
  245. File: gsl-ref.info,  Node: Root Finding References and Further Reading,  Prev: Root Finding Examples,  Up: One dimensional Root-Finding
  246.  
  247. References and Further Reading
  248. ==============================
  249.  
  250.    For information on the Brent-Dekker algorithm see the following two
  251. papers,
  252.  
  253.      R. P. Brent, "An algorithm with guaranteed convergence for finding
  254.      a zero of a function", `Computer Journal', 14 (1971) 422-425
  255.  
  256.      J. C. P. Bus and T. J. Dekker, "Two Efficient Algorithms with
  257.      Guaranteed Convergence for Finding a Zero of a Function", `ACM
  258.      Transactions of Mathematical Software', Vol. 1 No. 4 (1975) 330-345
  259.  
  260. 
  261. File: gsl-ref.info,  Node: Multidimensional Root-Finding,  Next: Minimization,  Prev: One dimensional Root-Finding,  Up: Top
  262.  
  263. Multidimensional Root-Finding
  264. *****************************
  265.  
  266.    This chapter describes functions for multidimensional root-finding
  267. (solving nonlinear systems with n equations in n unknowns).  The
  268. library provides low level components for a variety of iterative
  269. solvers and convergence tests.  These can be combined by the user to
  270. achieve the desired solution, with full access to the intermediate
  271. steps of the iteration.  Each class of methods uses the same framework,
  272. so that you can switch between solvers at runtime without needing to
  273. recompile your program.  Each instance of a solver keeps track of its
  274. own state, allowing the solvers to be used in multi-threaded programs.
  275.  
  276.    The header file `gsl_multiroots.h' contains prototypes for the
  277. multidimensional root finding functions and related declarations.
  278.  
  279. * Menu:
  280.  
  281. * Overview of Multidimensional Root Finding::
  282. * Initializing the Multidimensional Solver::
  283. * Providing the multidimensional system of equations to solve::
  284. * Iteration of the multidimensional solver::
  285. * Search Stopping Parameters for the multidimensional solver::
  286. * Algorithms using Derivatives::
  287. * Algorithms without Derivatives::
  288. * Example programs for Multidimensional Root finding::
  289. * References and Further Reading for Multidimensional Root Finding::
  290.  
  291. 
  292. File: gsl-ref.info,  Node: Overview of Multidimensional Root Finding,  Next: Initializing the Multidimensional Solver,  Up: Multidimensional Root-Finding
  293.  
  294. Overview
  295. ========
  296.  
  297.    The problem of multidimensional root finding requires the
  298. simultaneous solution of n equations, f_i, in n variables, x_i,
  299.  
  300.      f_i (x_1, ..., x_n) = 0    for i = 1 ... n.
  301.  
  302. In general there are no bracketing methods available for n dimensional
  303. systems, and no way of knowing whether any solutions exist.  All
  304. algorithms proceed from an initial guess using a variant of the Newton
  305. iteration,
  306.  
  307.      x -> x' = x - J^{-1} f(x)
  308.  
  309. where x, f are vector quantities and J is the Jacobian matrix J_{ij} =
  310. d f_i / d x_j.  Additional strategies are also used to enlarge the
  311. region of convergence.  These include requiring a decrease in the norm
  312. |f| on each step proposed by Newton's method, or taking downwards steps
  313. in the direction of the negative gradient of |f|.
  314.  
  315.    The evaluation of the Jacobian matrix can be problematic, either
  316. because programming the derivatives is intractable or because
  317. computation of the n^2 terms of the matrix becomes too expensive.  For
  318. these reasons the algorithms provided by the library are divided into
  319. two classes according to whether the derivatives are available or not.
  320.  
  321.    The state for solvers with an analytic Jacobian matrix is held in a
  322. `gsl_multiroot_fdfsolver' struct.  The updating procedure requires both
  323. the function and its derivatives to be supplied by the user.
  324.  
  325.    The state for solvers which do not use an analytic Jacobian matrix is
  326. held in a `gsl_multiroot_fsolver' struct.  The updating procedure uses
  327. only function evaluations (not derivatives).  The algorithms estimate
  328. the matrix J or J^{-1} by approximate methods.
  329.  
  330. 
  331. File: gsl-ref.info,  Node: Initializing the Multidimensional Solver,  Next: Providing the multidimensional system of equations to solve,  Prev: Overview of Multidimensional Root Finding,  Up: Multidimensional Root-Finding
  332.  
  333. Initializing the Solver
  334. =======================
  335.  
  336.  - Function: gsl_multiroot_fsolver * gsl_multiroot_fsolver_alloc (const
  337.           gsl_multiroot_fsolver_type * T, gsl_multiroot_function * F,
  338.           gsl_vector * X)
  339.      This function returns a pointer to a a newly allocated instance of
  340.      a solver of type T for the function F, with an initial bracket on
  341.      the root of X.  For example, the following code creates an
  342.      instance of a Brent solver,
  343.  
  344.           gsl_multiroot_fsolver * s =
  345.               gsl_multiroot_fsolver_alloc (gsl_multiroot_fsolver_brent, f, x);
  346.  
  347.      If there is insufficient memory to create the solver then the
  348.      function returns a null pointer and the error handler is invoked
  349.      with an error code of `GSL_ENOMEM'.
  350.  
  351.  - Function: gsl_multiroot_fdfsolver * gsl_multiroot_fdfsolver_alloc
  352.           (const gsl_multiroot_fdfsolver_type * T,
  353.           gsl_multiroot_function_fdf * FDF, gsl_vector * X)
  354.      This function returns a pointer to a a newly allocated instance of
  355.      a derivative solver of type T for the function FDF, with an
  356.      initial guess for the root of X.  For example, the following code
  357.      creates an instance of a Newton-Raphson solver,
  358.  
  359.           gsl_multiroot_fdfsolver * s =
  360.               gsl_multiroot_fdfsolver_alloc (gsl_multiroot_fdfsolver_newton, fdf, x);
  361.  
  362.      If there is insufficient memory to create the solver then the
  363.      function returns a null pointer and the error handler is invoked
  364.      with an error code of `GSL_ENOMEM'.
  365.  
  366.  - Function: int gsl_multiroot_fsolver_set (gsl_multiroot_fsolver * S,
  367.           gsl_multiroot_function * F, gsl_vector * X)
  368.      This function reinitializes an existing solver S to use the
  369.      function F and the initial guess X.
  370.  
  371.  - Function: int gsl_multiroot_fdfsolver_set (gsl_multiroot_fdfsolver *
  372.           S, gsl_function_fdf * FDF, gsl_vector * X)
  373.      This function reinitializes an existing solver S to use the
  374.      function and derivative FDF and the initial guess X.
  375.  
  376.  - Function: void gsl_multiroot_fsolver_free (gsl_multiroot_fsolver * S)
  377.  - Function: void gsl_multiroot_fdfsolver_free (gsl_multiroot_fdfsolver
  378.           * S)
  379.      These functions free all the memory associated with the solver S.
  380.  
  381.  - Function: const char * gsl_multiroot_fsolver_name (const
  382.           gsl_multiroot_fsolver * S)
  383.  - Function: const char * gsl_multiroot_fdfsolver_name (const
  384.           gsl_multiroot_fdfsolver * S)
  385.      These functions return a pointer to the name of the solver.  For
  386.      example,
  387.  
  388.           printf("s is a '%s' solver\n", gsl_multiroot_fdfsolver_name (s)) ;
  389.  
  390.      would print something like `s is a 'newton' solver'
  391.  
  392. 
  393. File: gsl-ref.info,  Node: Providing the multidimensional system of equations to solve,  Next: Iteration of the multidimensional solver,  Prev: Initializing the Multidimensional Solver,  Up: Multidimensional Root-Finding
  394.  
  395. Providing the function to solve
  396. ===============================
  397.  
  398.    You must provide n functions of n variables for the root finders to
  399. operate on.  In order to allow for general parameters the functions are
  400. defined by the following data types:
  401.  
  402.  - Data Type: gsl_multiroot_function
  403.      This data type defines a general system of functions with
  404.      parameters.
  405.  
  406.     `int (* f) (const gsl_vector * X, void * PARAMS, gsl_vector * F)'
  407.           this function should store the vector result f(x,params) in F
  408.           for argument X and parameters PARAMS, returning an
  409.           appropriate error code if the function cannot be computed.
  410.  
  411.     `size_t N'
  412.           the dimension of the system, i.e. the number of components of
  413.           the vectors X and F
  414.  
  415.     `void * PARAMS'
  416.           a pointer to the parameters of the function
  417.  
  418. Here is an example using Powell's test function,
  419.  
  420.      f_1(x) = A x_0 x_1 - 1,
  421.      f_2(x) = exp(-x_0) + exp(-x_1) - (1 + 1/A)
  422.  
  423. with A = 10^4.  The following code defines a `gsl_multiroot_function'
  424. system `F' which you could pass to a solver:
  425.  
  426.      struct powell_params { double A ; } ;
  427.      
  428.      int
  429.      powell (gsl_vector * x, void * p, gsl_vector * f) {
  430.         struct powell_params * params = *(struct powell_params *)p ;
  431.         double A = (params->A) ;
  432.         double x0 = gsl_vector_get(x,0);
  433.         double x1 = gsl_vector_get(x,1);
  434.         gsl_vector_set (f, 0, A * x0 * x1 - 1)
  435.         gsl_vector_set (f, 1, exp(-x0) + exp(-x1) - (1 + 1/A))
  436.         return GSL_SUCCESS
  437.      }
  438.      
  439.      gsl_multiroot_function F ;
  440.      struct powell_params params = { 10000.0 };
  441.      
  442.      F.function = &powell ;
  443.      F.n = 2 ;
  444.      F.params = ¶ms ;
  445.  
  446.  - Data Type: gsl_multiroot_function_fdf
  447.      This data type defines a general system of functions with
  448.      parameters and the corresponding Jacobian matrix of derivatives,
  449.  
  450.     `int (* f) (const gsl_vector * X, void * PARAMS, gsl_vector * F)'
  451.           this function should store the vector result f(x,params) in F
  452.           for argument X and parameters PARAMS, returning an
  453.           appropriate error code if the function cannot be computed.
  454.  
  455.     `int (* df) (const gsl_vector * X, void * PARAMS, gsl_matrix * J)'
  456.           this function should store the N-by-N matrix result J_ij = d
  457.           f_i(x,params) / d x_j in J for argument X and parameters
  458.           PARAMS, returning an appropriate error code if the function
  459.           cannot be computed.
  460.  
  461.     `int (* fdf) (const gsl_vector * X, void * PARAMS, gsl_vector * F, gsl_matrix * J)'
  462.           This function should set the values of the F and J as above,
  463.           for arguments X and parameters PARAMS.  This function provides
  464.           an optimization of the separate functions for f(x) and J(x) -
  465.           it is always faster to compute the function and its
  466.           derivative at the same time.
  467.  
  468.     `size_t N'
  469.           the dimension of the system, i.e. the number of components of
  470.           the vectors X and F
  471.  
  472.     `void * PARAMS'
  473.           a pointer to the parameters of the function
  474.  
  475. The example of Powell's test function defined above can be extended to
  476. include analytic derivatives using the following code,
  477.  
  478.      int
  479.      powell_df (gsl_vector * x, void * p, gsl_matrix * J) {
  480.         struct powell_params * params = *(struct powell_params *)p ;
  481.         double A = (params->A) ;
  482.         double x0 = gsl_vector_get(x,0);
  483.         double x1 = gsl_vector_get(x,1);
  484.         gsl_vector_set (df, 0, 0, A * x1)
  485.         gsl_vector_set (df, 0, 1, A * x0)
  486.         gsl_vector_set (df, 1, 0, -exp(-x0))
  487.         gsl_vector_set (df, 1, 1, -exp(-x1))
  488.         return GSL_SUCCESS
  489.      }
  490.      
  491.      int
  492.      powell_fdf (gsl_vector * x, void * p, gsl_matrix * f, gsl_matrix * J) {
  493.         struct powell_params * params = *(struct powell_params *)p ;
  494.         double A = (params->A) ;
  495.         double x0 = gsl_vector_get(x,0);
  496.         double x1 = gsl_vector_get(x,1);
  497.      
  498.         double u0 = exp(-x0);
  499.         double u1 = exp(-x1);
  500.      
  501.         gsl_vector_set (f, 0, A * x0 * x1 - 1)
  502.         gsl_vector_set (f, 1, u0 + u1 - (1 + 1/A))
  503.      
  504.         gsl_vector_set (J, 0, 0, A * x1)
  505.         gsl_vector_set (J, 0, 1, A * x0)
  506.         gsl_vector_set (J, 1, 0, -u0)
  507.         gsl_vector_set (J, 1, 1, -u1)
  508.         return GSL_SUCCESS
  509.      }
  510.      
  511.      gsl_multiroot_function_fdf FDF ;
  512.      
  513.      FDF.f = &powell_f ;
  514.      FDF.df = &powell_df ;
  515.      FDF.fdf = &powell_fdf ;
  516.      FDF.n = 2;
  517.      FDF.params = 0 ;
  518.  
  519. Note that the function `powell_fdf' is able to reuse existing terms
  520. from the function when calculating the Jacobian, thus saving time.
  521.  
  522. 
  523. File: gsl-ref.info,  Node: Iteration of the multidimensional solver,  Next: Search Stopping Parameters for the multidimensional solver,  Prev: Providing the multidimensional system of equations to solve,  Up: Multidimensional Root-Finding
  524.  
  525. Iteration
  526. =========
  527.  
  528.    The following functions drive the iteration of each algorithm.  Each
  529. function performs one iteration to update the state of any solver of the
  530. corresponding type.  The same functions work for all solvers so that
  531. different methods can be substituted at runtime without modifications to
  532. the code.
  533.  
  534.  - Function: int gsl_multiroot_fsolver_iterate (gsl_multiroot_fsolver *
  535.           S)
  536.  - Function: int gsl_multiroot_fdfsolver_iterate
  537.           (gsl_multiroot_fdfsolver * S)
  538.      These functions perform a single iteration of the solver S.  If the
  539.      iteration encounters an unexpected problem then an error code will
  540.      be returned,
  541.  
  542.     `GSL_EBADFUNC'
  543.           the iteration encountered a singular point where the function
  544.           or its derivative evaluated to `Inf' or `NaN'.
  545.  
  546.     `GSL_ENOPROG'
  547.           the iteration is not making any progress, preventing the
  548.           algorithm from continuing.
  549.  
  550.    The solver maintains a current best estimate of the root at all
  551. times.  The bracketing solvers also keep track of the current best
  552. interval bounding the root.  This information can be accessed with the
  553. following auxiliary functions,
  554.  
  555.  - Function: gsl_vector * gsl_multiroot_fsolver_root (const
  556.           gsl_multiroot_fsolver * S)
  557.  - Function: gsl_vector * gsl_multiroot_fdfsolver_root (const
  558.           gsl_multiroot_fdfsolver * S)
  559.      These functions return the current estimate of the root for the
  560.      solver S.
  561.  
  562. 
  563. File: gsl-ref.info,  Node: Search Stopping Parameters for the multidimensional solver,  Next: Algorithms using Derivatives,  Prev: Iteration of the multidimensional solver,  Up: Multidimensional Root-Finding
  564.  
  565. Search Stopping Parameters
  566. ==========================
  567.  
  568.    A root finding procedure should stop when one of the following
  569. conditions is true:
  570.  
  571.    * A multidimensional root has been found to within the
  572.      user-specified precision.
  573.  
  574.    * A user-specified maximum number of iterations has executed.
  575.  
  576.    * An error has occurred.
  577.  
  578. In the multidimensional root finding framework of GSL the handling of
  579. these conditions is under user control.  The functions below allow the
  580. user to test the precision of the current result in several standard
  581. ways.
  582.  
  583.  - Function: int gsl_multiroot_test_delta (const gsl_vector * DX, const
  584.           gsl_vector * X, double EPSABS, double EPSREL)
  585.      This function tests for the convergence of the sequence by
  586.      comparing the last step DX with the absolute error EPSABS and
  587.      relative error EPSREL to the current position X.  The test returns
  588.      `GSL_SUCCESS' if the following condition is achieved,
  589.  
  590.           |dx_i| < epsabs + epsrel |x_i|
  591.  
  592.      for each component of X and returns `GSL_CONTINUE' otherwise.
  593.  
  594.  - Function: int gsl_multiroot_test_residual (const gsl_vector * F,
  595.           double EPSABS)
  596.      This function tests the residual value F against the absolute
  597.      error bound EPSABS.  The test returns `GSL_SUCCESS' if the
  598.      following condition is achieved,
  599.  
  600.           \sum_i |f_i| < epsabs
  601.  
  602.      and returns `GSL_CONTINUE' otherwise.  This criterion is suitable
  603.      for situations where the the precise location of the root, x, is
  604.      unimportant provided a value can be found where the residual is
  605.      small enough.
  606.  
  607. 
  608. File: gsl-ref.info,  Node: Algorithms using Derivatives,  Next: Algorithms without Derivatives,  Prev: Search Stopping Parameters for the multidimensional solver,  Up: Multidimensional Root-Finding
  609.  
  610. Algorithms using Derivatives
  611. ============================
  612.  
  613.    The root finding algorithms described in this section make use of
  614. both the function and its derivative.  They require an initial guess
  615. for the location of the root, but there is no absolute guarantee of
  616. convergence - the function must be suitable for this technique and the
  617. initial guess must be sufficiently close to the root for it to work.
  618. When the conditions are satisfied then convergence is quadratic.
  619.  
  620.  - Derivative Solver: gsl_multiroot_fdfsolver_hybridsj
  621.      This is a modified version of Powell's Hybrid method as
  622.      implemented in the HYBRJ algorithm in MINPACK.  Minpack was
  623.      written by Jorge J. More', Burton S. Garbow and Kenneth E.
  624.      Hillstrom.  The Hybrid algorithm retains the fast convergence of
  625.      Newton's method but will also reduce the residual when Newton's
  626.      method is unreliable.
  627.  
  628.      The algorithm uses a generalized trust region to keep each step
  629.      under control.  In order to be accepted a proposed new position x'
  630.      must satisfy the condition |D (x' - x)| < \delta, where D is a
  631.      diagonal scaling matrix and \delta is the size of the trust
  632.      region.  The components of D are computed internally, using the
  633.      column norms of the Jacobian to estimate the sensitivity of the
  634.      residual to each component of x.  This improves the behavior of the
  635.      algorithm for badly scaled functions.
  636.  
  637.      On each iteration the algorithm first determines the standard
  638.      Newton step by solving the system J dx = - f.  If this step falls
  639.      inside the trust region it is used as a trial step in the next
  640.      stage.  If not, the algorithm uses the linear combination of the
  641.      Newton and Gradient directions which is predicted to minimize the
  642.      norm of the function while staying inside the trust region.
  643.  
  644.           dx = - \alpha J^{-1} f(x) - \beta \nabla |f(x)|^2
  645.  
  646.      This combination of Newton and Gradient directions is referred to
  647.      as a "dogleg step".
  648.  
  649.      The proposed step is now tested by evaluating the function at the
  650.      resulting point, x'.  If the step reduces the norm of the function
  651.      sufficiently then it is accepted and size of the trust region is
  652.      increased.  If the proposed step fails to improve the solution
  653.      then the size of the trust region is decreased and another trial
  654.      step is computed.
  655.  
  656.      The speed of the algorithm is increased by computing the changes
  657.      to the Jacobian approximately, using a rank-1 update.  If two
  658.      successive attempts fail to reduce the residual then the full
  659.      Jacobian is recomputed.  The algorithm also monitors the progress
  660.      of the solution and returns an error if several steps fail to make
  661.      any improvement,
  662.  
  663.     `GSL_ENOPROG'
  664.           the iteration is not making any progress, preventing the
  665.           algorithm from continuing.
  666.  
  667.     `GSL_ENOPROGJ'
  668.           re-evaluations of the Jacobian indicate that the iteration is
  669.           not making any progress, preventing the algorithm from
  670.           continuing.
  671.  
  672.  
  673.  - Derivative Solver: gsl_multiroot_fdfsolver_hybridj
  674.      This algorithm is an unscaled version of `hybridsj'.  The steps are
  675.      controlled by a spherical trust region |x' - x| < \delta, instead
  676.      of a generalized region.  This can be useful if the generalized
  677.      region estimated by `hybridsj' is inappropriate.
  678.  
  679.  - Derivative Solver: gsl_multiroot_fdfsolver_newton
  680.      Newton's Method is the standard root-polishing algorithm.  The
  681.      algorithm begins with an initial guess for the location of the
  682.      solution.  On each iteration a linear approximation to the
  683.      function F is used to estimate the step which will zero all the
  684.      components of the residual.  The iteration is defined by the
  685.      following sequence,
  686.  
  687.           x -> x' = x - J^{-1} f(x)
  688.  
  689.      where the Jacobian matrix J is computed from the derivative
  690.      functions provided by F.  The step dx is obtained by solving the
  691.      linear system,
  692.  
  693.           J dx = - f(x)
  694.  
  695.      using LU decomposition.
  696.  
  697.  - Derivative Solver: gsl_multiroot_fdfsolver_gnewton
  698.      This is a modified version of Newtons method which attempts to
  699.      improve global convergence by requiring every step to reduce the
  700.      Euclidean norm of the residual, |f(x)|.  If the Newton step leads
  701.      to an increase in the norm then a reduced step of relative size
  702.  
  703.           t = (\sqrt(1 + 6 r) - 1) / (3 r)
  704.  
  705.      is proposed, with r being the ratio of norms |f(x')|^2/|f(x)|^2.
  706.      This procedure is repeated until a suitable step size is found.
  707.  
  708. 
  709. File: gsl-ref.info,  Node: Algorithms without Derivatives,  Next: Example programs for Multidimensional Root finding,  Prev: Algorithms using Derivatives,  Up: Multidimensional Root-Finding
  710.  
  711. Algorithms without Derivatives
  712. ==============================
  713.  
  714.    The algorithms described in this section do not require any
  715. derivative information to be supplied by the user.  Any derivatives
  716. needed are approximated from by finite difference.
  717.  
  718.  - Solver: gsl_multiroot_fsolver_hybrids
  719.      This is a version of the Hybrid algorithm which replaces calls to
  720.      the Jacobian function by its finite difference approximation.  The
  721.      finite difference approximation is computed using
  722.      `gsl_multiroots_fdjac' with a relative step size of
  723.      `GSL_SQRT_DBL_EPSILON'.
  724.  
  725.  - Solver: gsl_multiroot_fsolver_hybrid
  726.      This is a finite difference version of the Hybrid algorithm without
  727.      internal scaling.
  728.  
  729.  - Solver: gsl_multiroot_fsolver_dnewton
  730.      The "discrete Newton algorithm" is the simplest method of solving a
  731.      multidimensional system.  It uses the Newton iteration
  732.  
  733.           x -> x - J^{-1} f(x)
  734.  
  735.      where the Jacobian matrix J is approximated by taking finite
  736.      differences of the function F.  The approximation scheme used by
  737.      this implementation is,
  738.  
  739.           J_{ij} = (f_i(x + \delta_j) - f_i(x)) /  \delta_j
  740.  
  741.      where \delta_j is a step of size \sqrt\epsilon |x_j| with \epsilon
  742.      being the machine precision (\epsilon \approx 2.22 \times 10^-16).
  743.      The order of convergence of Newton's algorithm is quadratic, but
  744.      the finite differences require n^2 function evaluations on each
  745.      iteration.  The algorithm may become unstable if the finite
  746.      differences are not a good approximation to the true derivatives.
  747.  
  748.  - Solver: gsl_multiroot_fsolver_broyden
  749.      The "Broyden algorithm" is a version of the discrete Newton
  750.      algorithm which attempts to avoids the expensive update of the
  751.      Jacobian matrix on each iteration.  The changes to the Jacobian
  752.      are also approximated, using a rank-1 update,
  753.  
  754.           J^{-1} \to J^{-1} - (J^{-1} df - dx) dx^T J^{-1} / dx^T J^{-1} df
  755.  
  756.      where the vectors dx and df are the changes in x and f.  On the
  757.      first iteration the inverse Jacobian is estimated using finite
  758.      differences, as in the discrete Newton algorithm.
  759.  
  760.      This approximation gives a fast update but is unreliable if the
  761.      changes are not small, and the estimate of the inverse Jacobian
  762.      becomes worse as time passes.  The algorithm has a tendency to
  763.      become unstable unless it starts close to the root.  The Jacobian
  764.      is refreshed if this instability is detected (consult the source
  765.      for details).
  766.  
  767.      This algorithm is not recommended for real work and is included
  768.      only for pedagogical purposes.
  769.  
  770. 
  771. File: gsl-ref.info,  Node: Example programs for Multidimensional Root finding,  Next: References and Further Reading for Multidimensional Root Finding,  Prev: Algorithms without Derivatives,  Up: Multidimensional Root-Finding
  772.  
  773. Examples
  774. ========
  775.  
  776.    The multidimensional solvers are used in a similar way to the
  777. one-dimensional root finding algorithms.  This first example
  778. demonstrates the `hybrids' scaled-hybrid algorithm, which does not
  779. require derivatives. The program solves the Rosenbrock system of
  780. equations
  781.  
  782.      f_1 (x, y) = a (1 - x)
  783.      f_2 (x, y) = b (y - x^2)
  784.  
  785. with a = 1, b = 10. The solution of this system lies at (x,y) = (1,1)
  786. in a narrow valley.
  787.  
  788.    The first stage of the program is to define the system of equations,
  789.  
  790.      #include <stdlib.h>
  791.      #include <stdio.h>
  792.      #include <gsl/gsl_vector.h>
  793.      #include <gsl/gsl_multiroots.h>
  794.      
  795.      struct rparams
  796.        {
  797.          double a;
  798.          double b;
  799.        };
  800.      
  801.      int
  802.      rosenbrock_f (const gsl_vector * x, void *params, gsl_vector * f)
  803.      {
  804.        double a = ((struct rparams *) params)->a;
  805.        double b = ((struct rparams *) params)->b;
  806.      
  807.        double x0 = gsl_vector_get (x, 0);
  808.        double x1 = gsl_vector_get (x, 1);
  809.      
  810.        double y0 = a * (1 - x0);
  811.        double y1 = b * (x1 - x0 * x0);
  812.      
  813.        gsl_vector_set (f, 0, y0);
  814.        gsl_vector_set (f, 1, y1);
  815.      
  816.        return GSL_SUCCESS;
  817.      }
  818.  
  819. The main program begins by creating the function object `f', with the
  820. arguments `(x,y)' and parameters `(a,b)'. The solver `s' is initialized
  821. to use this function, with the `hybrids' method.
  822.  
  823.      int
  824.      main (void)
  825.      {
  826.        const gsl_multiroot_fsolver_type *T;
  827.        gsl_multiroot_fsolver *s;
  828.      
  829.        int status;
  830.        size_t i, iter = 0;
  831.      
  832.        const size_t n = 2;
  833.        struct rparams p = {1.0, 10.0};
  834.        gsl_multiroot_function f = {&rosenbrock_f, n, &p};
  835.      
  836.        double x_init[2] = {-10.0, -5.0};
  837.        gsl_vector *x = gsl_vector_alloc (n);
  838.      
  839.        gsl_vector_set (x, 0, x_init[0]);
  840.        gsl_vector_set (x, 1, x_init[1]);
  841.      
  842.        T = gsl_multiroot_fsolver_hybrids;
  843.        s = gsl_multiroot_fsolver_alloc (T, &f, x);
  844.      
  845.        print_state (iter, s);
  846.      
  847.        do
  848.          {
  849.            iter++;
  850.            status = gsl_multiroot_fsolver_iterate (s);
  851.      
  852.            print_state (iter, s);
  853.      
  854.            if (status)   /* check if solver is stuck */
  855.              break;
  856.      
  857.            status = gsl_multiroot_test_residual (s->f, 0.0000001);
  858.          }
  859.        while (status == GSL_CONTINUE && iter < 1000);
  860.      
  861.        printf ("status = %s\n", gsl_strerror (status));
  862.      
  863.        gsl_multiroot_fsolver_free (s);
  864.        gsl_vector_free (x);
  865.      }
  866.  
  867. Note that it is important to check the return status of each solver
  868. step, in case the algorithm becomes stuck.  If an error condition is
  869. detected, indicating that the algorithm cannot proceed, then the error
  870. can be reported to the user, a new starting point chosen or a different
  871. algorithm used.
  872.  
  873.    The intermediate state of the solution is displayed by the following
  874. function.  The solver state contains the vector `s->x' which is the
  875. current position, and the vector `s->f' with corresponding function
  876. values.
  877.      int
  878.      print_state (size_t iter, gsl_multiroot_fsolver * s)
  879.      {
  880.        printf ("iter = %3u x = % 10.3f % 10.3f  f(x) = % .3e % .3e\n",
  881.            iter,
  882.            gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1),
  883.            gsl_vector_get (s->f, 0), gsl_vector_get (s->f, 1));
  884.      }
  885.  
  886. Here are the results of running the program. The algorithm is started at
  887. (-10,-5) far from the solution.  Since the solution is hidden in a
  888. narrow valley the earliest steps follow the gradient of the function
  889. downhill, in an attempt to reduce the large value of the residual. Once
  890. the root has been approximately located, on iteration 8, the Newton
  891. behavior takes over and convergence is very rapid.
  892.  
  893.      iter =   0 x =  -10.00000000  -5.00000000  f(x) =  1.100e+01 -1.050e+03
  894.      iter =   1 x =  -10.00000000  -5.00000000  f(x) =  1.100e+01 -1.050e+03
  895.      iter =   2 x =   -3.97577039  24.82704463  f(x) =  4.976e+00  9.020e+01
  896.      iter =   3 x =   -3.97577039  24.82704463  f(x) =  4.976e+00  9.020e+01
  897.      iter =   4 x =   -3.97577039  24.82704463  f(x) =  4.976e+00  9.020e+01
  898.      iter =   5 x =   -1.27350954  -5.67999688  f(x) =  2.274e+00 -7.302e+01
  899.      iter =   6 x =   -1.27350954  -5.67999688  f(x) =  2.274e+00 -7.302e+01
  900.      iter =   7 x =    0.24894860   0.29786482  f(x) =  7.511e-01  2.359e+00
  901.      iter =   8 x =    0.24894860   0.29786482  f(x) =  7.511e-01  2.359e+00
  902.      iter =   9 x =    1.00000000   0.87821493  f(x) =  1.268e-10 -1.218e+00
  903.      iter =  10 x =    1.00000000   0.98919827  f(x) =  1.124e-11 -1.080e-01
  904.      iter =  11 x =    1.00000000   1.00000000  f(x) =  0.000e+00  0.000e+00
  905.      status = success
  906.  
  907. Note that the algorithm does not update the location on every
  908. iteration. Some iterations are used to adjust the trust-region
  909. parameter, after trying a step which was found to be divergent, or to
  910. recompute the Jacobian, when poor convergence behavior is detected.
  911.  
  912.    The next example program adds derivative information, in order to
  913. accelerate the solution. There are two derivative functions
  914. `rosenbrock_df' and `rosenbrock_fdf'. The latter computes both the
  915. function and its derivative simultaneously. This allows the
  916. optimization of any common terms.  For simplicity we substitute calls to
  917. the separate `f' and `df' functions at this point in the code below.
  918.  
  919.      int
  920.      rosenbrock_df (const gsl_vector * x, void *params, gsl_matrix * df)
  921.      {
  922.        double a = ((struct rparams *) params)->a;
  923.        double b = ((struct rparams *) params)->b;
  924.      
  925.        double x0 = gsl_vector_get (x, 0);
  926.      
  927.        double df00 = -a;
  928.        double df01 = 0;
  929.        double df10 = -2 * b  * x0;
  930.        double df11 = b;
  931.      
  932.        gsl_matrix_set (df, 0, 0, df00);
  933.        gsl_matrix_set (df, 0, 1, df01);
  934.        gsl_matrix_set (df, 1, 0, df10);
  935.        gsl_matrix_set (df, 1, 1, df11);
  936.      
  937.        return GSL_SUCCESS;
  938.      }
  939.      
  940.      int
  941.      rosenbrock_fdf (const gsl_vector * x, void *params,
  942.              gsl_vector * f, gsl_matrix * df)
  943.      {
  944.        rosenbrock_f (x, params, f);
  945.        rosenbrock_df (x, params, df);
  946.      
  947.        return GSL_SUCCESS;
  948.      }
  949.  
  950. The main program now makes calls to the corresponding `fdfsolver'
  951. versions of the functions,
  952.  
  953.      int
  954.      main (void)
  955.      {
  956.        const gsl_multiroot_fdfsolver_type *T;
  957.        gsl_multiroot_fdfsolver *s;
  958.      
  959.        int status;
  960.        size_t i, iter = 0;
  961.      
  962.        const size_t n = 2;
  963.        struct rparams p = {1.0, 10.0};
  964.        gsl_multiroot_function_fdf f = {&rosenbrock_f,
  965.                                        &rosenbrock_df,
  966.                                        &rosenbrock_fdf, n, &p};
  967.      
  968.        double x_init[2] = {-10.0, -5.0};
  969.        gsl_vector *x = gsl_vector_alloc (n);
  970.      
  971.        gsl_vector_set (x, 0, x_init[0]);
  972.        gsl_vector_set (x, 1, x_init[1]);
  973.      
  974.        T = gsl_multiroot_fdfsolver_gnewton;
  975.        s = gsl_multiroot_fdfsolver_alloc (T, &f, x);
  976.      
  977.        print_state (iter, s);
  978.      
  979.        do
  980.          {
  981.            iter++;
  982.      
  983.            status = gsl_multiroot_fdfsolver_iterate (s);
  984.      
  985.            print_state (iter, s);
  986.      
  987.            if (status)
  988.              break;
  989.      
  990.            status = gsl_multiroot_test_residual (s->f, 0.0000001);
  991.          }
  992.        while (status == GSL_CONTINUE && iter < 1000);
  993.      
  994.        printf ("status = %s\n", gsl_strerror (status));
  995.      
  996.        gsl_multiroot_fdfsolver_free (s);
  997.        gsl_vector_free (x);
  998.      }
  999.  
  1000. The addition of derivative information to the `hybrids' solver does not
  1001. make any significant difference to its behavior, since it able to
  1002. approximate the Jacobian numerically with sufficient accuracy.  To
  1003. illustrate the behavior of a different derivative solver we switch to
  1004. `gnewton'. This is a traditional newton solver with the constraint that
  1005. it scales back its step if the full step would lead "uphill". Here is
  1006. the output for the `gnewton' algorithm,
  1007.  
  1008.      iter =  0 x = -10.00000000  -5.00000000  f(x) =  1.100e+01 -1.050e+03
  1009.      iter =  1 x =  -4.23051697 -65.31732261  f(x) =  5.231e+00 -8.321e+02
  1010.      iter =  2 x =   1.00000000 -26.35830775  f(x) = -8.882e-16 -2.736e+02
  1011.      iter =  3 x =   1.00000000   1.00000000  f(x) = -2.220e-16 -4.441e-15
  1012.      status = success
  1013.  
  1014. The convergence is much more rapid, but takes a wide excursion out to
  1015. the point (-4.23,-65.3). This could lead to algorithm going astray in a
  1016. realistic application.  The hybrid algorithm follows the downhill path
  1017. to the solution more reliably.
  1018.  
  1019. 
  1020. File: gsl-ref.info,  Node: References and Further Reading for Multidimensional Root Finding,  Prev: Example programs for Multidimensional Root finding,  Up: Multidimensional Root-Finding
  1021.  
  1022. References and Further Reading
  1023. ==============================
  1024.  
  1025.    The original version of the Hybrid method is described in the
  1026. following articles by Powell,
  1027.  
  1028.      M.J.D. Powell, "A Hybrid Method for Nonlinear Equations" (Chap 6, p
  1029.      87-114) and "A Fortran Subroutine for Solving systems of Nonlinear
  1030.      Algebraic Equations" (Chap 7, p 115-161), in `Numerical Methods for
  1031.      Nonlinear Algebraic Equations', P. Rabinowitz, editor.  Gordon and
  1032.      Breach, 1970.
  1033.  
  1034. The following papers are also relevant to the algorithms described in
  1035. this section,
  1036.  
  1037.      J.J. More', M.Y. Cosnard, "Numerical Solution of Nonlinear
  1038.      Equations", `ACM Transactions on Mathematical Software', Vol 5, No
  1039.      1, (1979), p 64-85
  1040.  
  1041.      C.G. Broyden, "A Class of Methods for Solving Nonlinear
  1042.      Simultaneous Equations", `Mathematics of Computation', Vol 19
  1043.      (1965), p 577-593
  1044.  
  1045.      J.J. More', B.S. Garbow, K.E. Hillstrom, "Testing Unconstrained
  1046.      Optimization Software", ACM Transactions on Mathematical Software,
  1047.      Vol 7, No 1 (1981), p 17-41
  1048.  
  1049. 
  1050. File: gsl-ref.info,  Node: Minimization,  Next: Simulated Annealing,  Prev: Multidimensional Root-Finding,  Up: Top
  1051.  
  1052. Minimization
  1053. ************
  1054.  
  1055.    This chapter describes functions for finding minima of arbitrary
  1056. one-dimensional functions.  The library provides low level components
  1057. for a variety of iterative minimizers and convergence tests.  These can
  1058. be combined by the user to achieve the desired solution, with full
  1059. access to the intermediate steps of the algorithms.  Each class of
  1060. methods uses the same framework, so that you can switch between
  1061. minimizers at runtime without needing to recompile your program.  Each
  1062. instance of a minimizer keeps track of its own state, allowing the
  1063. minimizers to be used in multi-threaded programs.
  1064.  
  1065.    The header file `gsl_min.h' contains prototypes for the minimization
  1066. functions and related declarations.  To use the minimization algorithms
  1067. to find the maximum of a function simply invert its sign.
  1068.  
  1069. * Menu:
  1070.  
  1071. * Minimization Overview::
  1072. * Minimization Caveats::
  1073. * Initializing the Minimizer::
  1074. * Providing the function to minimize::
  1075. * Minimization Iteration::
  1076. * Minimization Stopping Parameters::
  1077. * Minimization Algorithms::
  1078. * Minimization Examples::
  1079. * Minimization References and Further Reading::
  1080.  
  1081. 
  1082. File: gsl-ref.info,  Node: Minimization Overview,  Next: Minimization Caveats,  Up: Minimization
  1083.  
  1084. Overview
  1085. ========
  1086.  
  1087.    The minimization algorithms begin with a bounded region known to
  1088. contain a minimum.  The region is described by an lower bound a and an
  1089. upper bound b, with an estimate of the minimum x.
  1090.  
  1091. The value of the function at x must be less than the value of the
  1092. function at the ends of the interval,
  1093.  
  1094.      f(a) > f(x) < f(b)
  1095.  
  1096. This condition guarantees that a minimum is contained somewhere within
  1097. the interval.  On each iteration a new point x' is selected using one
  1098. of the available algorithms.  If the new point is a better estimate of
  1099. the minimum, f(x') < f(x), then the current estimate of the minimum x
  1100. is updated.  The new point also allows the size of the bounded interval
  1101. to be reduced, by choosing the most compact set of points which
  1102. satisfies the constraint f(a) > f(x) < f(b).  The interval is reduced
  1103. until it encloses the true minimum to a desired tolerance.  This
  1104. provides a best estimate of the location of the minimum and a rigorous
  1105. error estimate.
  1106.  
  1107.    In GSL different bracketing algorithms are available in a similar
  1108. framework.  The user provides a high-level driver for the algorithms,
  1109. and the library provides the individual functions necessary for each of
  1110. the steps.  There are three main phases of the iteration.  The steps
  1111. are,
  1112.  
  1113.    * initialize minimizer state, S, for algorithm T
  1114.  
  1115.    * update S using the iteration T
  1116.  
  1117.    * test S for convergence, and repeat iteration if necessary
  1118.  
  1119. The state for the minimizers is held in a `gsl_min_fminimizer' struct.
  1120. The updating procedure uses only function evaluations (not derivatives).
  1121.  
  1122. 
  1123. File: gsl-ref.info,  Node: Minimization Caveats,  Next: Initializing the Minimizer,  Prev: Minimization Overview,  Up: Minimization
  1124.  
  1125. Caveats
  1126. =======
  1127.  
  1128.    Note that minimization functions can only search for one minimum at a
  1129. time.  When there are several minima in the search area, the first
  1130. minimum to be found will be returned; however it is difficult to predict
  1131. which of the minima this will be. _In most cases, no error will be
  1132. reported if you try to find a minimum in an area where there is more
  1133. than one._
  1134.  
  1135.    With all minimization algorithms it can be difficult to determine the
  1136. location of the minimum to full numerical precision.  The behavior of
  1137. the function in the region of the minimum x^* can be approximated by a
  1138. Taylor expansion,
  1139.  
  1140.      y = f(x^*) + (1/2) f''(x^*) (x - x^*)^2
  1141.  
  1142. and the second term of this expansion can be lost when added to the
  1143. first term at finite precision.  This magnifies the error in locating
  1144. x^*, making it proportional to \sqrt \epsilon (where \epsilon is the
  1145. relative accuracy of the floating point numbers).  For functions with
  1146. higher order minima, such as x^4, the magnification of the error is
  1147. correspondingly worse.  The best that can be achieved is to converge to
  1148. the limit of numerical accuracy in the function values, rather than the
  1149. location of the minimum itself.
  1150.  
  1151. 
  1152. File: gsl-ref.info,  Node: Initializing the Minimizer,  Next: Providing the function to minimize,  Prev: Minimization Caveats,  Up: Minimization
  1153.  
  1154. Initializing the Minimizer
  1155. ==========================
  1156.  
  1157.  - Function: gsl_min_fminimizer * gsl_min_fminimizer_alloc (const
  1158.           gsl_min_fminimizer_type * T, gsl_function * F, double
  1159.           MINIMUM, gsl_interval X)
  1160.      This function returns a pointer to a a newly allocated instance of
  1161.      a minimizer of type T for the function F, with an initial bracket
  1162.      on the minimum of X containing a guess for the location of the
  1163.      minimum MINIMUM.  For example, the following code creates an
  1164.      instance of a golden section minimizer,
  1165.  
  1166.           gsl_min_fminimizer * s =
  1167.               gsl_min_fminimizer_alloc (gsl_min_fminimizer_goldensection);
  1168.  
  1169.      If there is insufficient memory to create the minimizer then the
  1170.      function returns a null pointer and the error handler is invoked
  1171.      with an error code of `GSL_ENOMEM'.
  1172.  
  1173.  - Function: gsl_min_fminimizer * gsl_min_fminimizer_alloc_with_values
  1174.           (const gsl_min_fminimizer_type * T, gsl_function * F, double
  1175.           MINIMUM, double F_MINIMUM, gsl_interval X, double F_LOWER,
  1176.           double F_UPPER)
  1177.      This function is equivalent to `gsl_min_fminimizer_alloc' but uses
  1178.      the values F_MINIMUM, F_LOWER and F_UPPER instead of computing
  1179.      `f(minimum)', `f(x.lower)' and `f(x.upper)'.
  1180.  
  1181.  - Function: int gsl_min_fminimizer_set (gsl_min_fminimizer * S,
  1182.           gsl_function * F, double MINIMUM, gsl_interval X)
  1183.      This function reinitializes an existing minimizer S to use the
  1184.      function F and the initial search interval X, with a guess for the
  1185.      location of the minimum MINIMUM.
  1186.  
  1187.  - Function: int gsl_min_fminimizer_set_with_values (gsl_min_fminimizer
  1188.           * S, gsl_function * F, double MINIMUM, double F_MINIMUM,
  1189.           gsl_interval X, double F_LOWER, double F_UPPER)
  1190.      This function is equivalent to `gsl_min_fminimizer_set' but uses
  1191.      the values F_MINIMUM, F_LOWER and F_UPPER instead of computing
  1192.      `f(minimum)', `f(x.lower)' and `f(x.upper)'.
  1193.  
  1194.  - Function: void gsl_min_fminimizer_free (gsl_min_fminimizer * S)
  1195.      This function frees all the memory associated with the minimizer S.
  1196.  
  1197.  - Function: const char * gsl_min_fminimizer_name (const
  1198.           gsl_min_fminimizer * S)
  1199.      This function returns a pointer to the name of the minimizer.  For
  1200.      example,
  1201.  
  1202.           printf("s is a '%s' minimizer\n", gsl_min_fminimizer_name (s)) ;
  1203.  
  1204.      would print something like `s is a 'brent' minimizer'
  1205.  
  1206. 
  1207. File: gsl-ref.info,  Node: Providing the function to minimize,  Next: Minimization Iteration,  Prev: Initializing the Minimizer,  Up: Minimization
  1208.  
  1209. Providing the function to minimize
  1210. ==================================
  1211.  
  1212.    You must provide a continuous function of one variable for the
  1213. minimizers to operate on.  In order to allow for general parameters the
  1214. functions are defined by a `gsl_function' data type (*note Providing
  1215. the function to solve::.).
  1216.  
  1217. 
  1218. File: gsl-ref.info,  Node: Minimization Iteration,  Next: Minimization Stopping Parameters,  Prev: Providing the function to minimize,  Up: Minimization
  1219.  
  1220. Iteration
  1221. =========
  1222.  
  1223.    The following functions drive the iteration of each algorithm.  Each
  1224. function performs one iteration to update the state of any minimizer of
  1225. the corresponding type.  The same functions work for all minimizers so
  1226. that different methods can be substituted at runtime without
  1227. modifications to the code.
  1228.  
  1229.  - Function: int gsl_min_fminimizer_iterate (gsl_min_fminimizer * S)
  1230.      This function performs a single iteration of the minimizer S.  If
  1231.      the iteration encounters an unexpected problem then an error code
  1232.      will be returned,
  1233.  
  1234.     `GSL_EBADFUNC'
  1235.           the iteration encountered a singular point where the function
  1236.           evaluated to `Inf' or `NaN'.
  1237.  
  1238.     `GSL_FAILURE'
  1239.           the algorithm could not improve the current best
  1240.           approximation or bounding interval.
  1241.  
  1242.    The minimizer maintains a current best estimate of the minimum at all
  1243. times, and the current interval bounding the minimum.  This information
  1244. can be accessed with the following auxiliary functions,
  1245.  
  1246.  - Function: double gsl_min_fminimizer_minimum (const
  1247.           gsl_min_fminimizer * S)
  1248.      This function returns the current estimate of the minimum for the
  1249.      minimizer S.
  1250.  
  1251.  - Function: gsl_interval gsl_min_fminimizer_interval (const
  1252.           gsl_min_fminimizer * S)
  1253.      This function returns the current bounding interval for the
  1254.      minimizer S.
  1255.  
  1256. 
  1257. File: gsl-ref.info,  Node: Minimization Stopping Parameters,  Next: Minimization Algorithms,  Prev: Minimization Iteration,  Up: Minimization
  1258.  
  1259. Stopping Parameters
  1260. ===================
  1261.  
  1262.    A minimization procedure should stop when one of the following
  1263. conditions is true:
  1264.  
  1265.    * A minimum has been found to within the user-specified precision.
  1266.  
  1267.    * A user-specified maximum number of iterations has executed.
  1268.  
  1269.    * An error has occurred.
  1270.  
  1271. In the minimization framework of GSL the handling of these conditions is
  1272. under user control.  The function below allows the user to test the
  1273. precision of the current result.
  1274.  
  1275.  - Function: int gsl_min_test_interval (gsl_interval X, double EPSREL,
  1276.           double EPSABS)
  1277.      This function tests for the convergence of the interval X with
  1278.      absolute error EPSABS and relative error EPSREL.  The test returns
  1279.      `GSL_SUCCESS' if the following condition is achieved,
  1280.  
  1281.           |a - b| < epsabs + epsrel min(|a|,|b|)
  1282.  
  1283.      when the interval x = [a,b] does not include the origin.  If the
  1284.      interval includes the origin then \min(|a|,|b|) is replaced by
  1285.      zero (which is the minimum value of |x| over the interval).  This
  1286.      ensures that the relative error is accurately estimated for minima
  1287.      close to the origin.
  1288.  
  1289.      This condition on the interval also implies that any estimate of
  1290.      the minimum x_m in the interval satisfies the same condition with
  1291.      respect to the true minimum x_m^*,
  1292.  
  1293.           |x_m - x_m^*| < epsabs + epsrel x_m^*
  1294.  
  1295.      assuming that the true minimum x_m^* is contained within the
  1296.      interval.
  1297.  
  1298.